package net.zjitc.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import net.zjitc.common.ResponseResult;
import net.zjitc.common.lang.Const;
import net.zjitc.common.lang.LevelStr;
import net.zjitc.entity.Manager;
import net.zjitc.entity.Permission;
import net.zjitc.entity.PermissionApi;
import net.zjitc.entity.Role;
import net.zjitc.exception.RoleException;
import net.zjitc.mapper.ManagerMapper;
import net.zjitc.mapper.PermissionApiMapper;
import net.zjitc.mapper.PermissionMapper;
import net.zjitc.mapper.RoleMapper;
import net.zjitc.service.RoleService;
import net.zjitc.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @Author 毛钰深
 * @Create 2021/12/29 20:42
 */
@Service
@Transactional
public class IRoleService implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ManagerMapper managerMapper;

    @Autowired
    private PermissionApiMapper permissionApiMapper;


    /**
     *已重构,还未完成对删除后的父子节点筛选(会有数据冗余)
     */
    @Override
    public ResponseResult selectRole() {
        ResponseResult<List<Role>> res=new ResponseResult<>();
        List<Role> roles = roleMapper.selectList(null);
        List<Permission> permissionList = permissionMapper.selectList(null);
        List<PermissionApi> permissionApis = permissionApiMapper.selectList(null);
        roles.forEach(role -> {
            //清理地址指向问题
            permissionList.forEach(p -> p.setChildren(null));

            if (!"".equals(role.getPsIds())&&role.getPsIds()!=null){
                List<Integer> rolePsIds = Arrays.stream(role.getPsIds().split(",")).map(Integer::parseInt).collect(Collectors.toList());

                List<Permission> children=new ArrayList<>();
                permissionList.forEach(permission -> {
                    if (rolePsIds.contains(permission.getId())){
                        children.add(permission);
                    }
                });
                List<Permission> levelOne=mnt(children,permissionApis);

                //注意处理因为地址引用产生的错误地址指向,需要new一个新的List来接受这些数据(clean方法实现)
                role.setChildren(clean(levelOne));
                role.setPsIds(null);
            }
        });
        res.setSuccess("获取成功",roles);
        return res;
    }

    private List<Permission> getPermissionByLevel(List<Permission> permissionList, String level, List<PermissionApi> permissionApis) {
        List<Permission> permissions=new ArrayList<>();
        permissionList.forEach(permission -> {
            if (level.equals(permission.getLevel())){
                for (PermissionApi permissionApi : permissionApis) {
                    if (permissionApi.getPs_id().equals(permission.getId())){
                        permission.setPath(permissionApi.getPs_api_path());
                    }
                }
                permissions.add(permission);
            }

        });
        return permissions;
    }

    private List<Permission> mnt( List<Permission> children,List<PermissionApi> permissionApis) {
        List<Permission> levelOne=getPermissionByLevel(children, LevelStr.LEVEL_ONE_STR.level,permissionApis);
        List<Permission> levelTwo=getPermissionByLevel(children,LevelStr.LEVEL_TWO_STR.level, permissionApis);
        List<Permission> levelThree=getPermissionByLevel(children,LevelStr.LEVEL_THREE_STR.level, permissionApis);
        merge(levelOne,levelTwo);
        merge(levelTwo,levelThree);
        return levelOne;
    }

    /**
     * 递归实现防止地址指向错误
     * @param levelOne
     * @return
     */
    private List<Permission> clean(List<Permission> levelOne) {
        List<Permission> list=new ArrayList<>();
        levelOne.forEach(l ->{
            List<Permission> ps=new ArrayList<>();
            //排除为null,元素为0的情况
            if (l.getChildren()!=null&&l.getChildren().size()!=0){
                ps=clean(l.getChildren());
            }
            Permission p=new Permission();
            p.setId(l.getId());
            p.setPid(l.getPid());
            p.setLevel(l.getLevel());
            p.setPath(l.getPath());
            p.setAuthName(l.getAuthName());
            //判断是否存在有效值,防止返回空的数组,而不是null值
            if (ps.size()!=0){
                p.setChildren(ps);
            }
            list.add(p);
        });
        return list;
    }

    private void merge(List<Permission> parent, List<Permission> children) {
        parent.forEach(p -> {
            List<Permission> child=new ArrayList<>();
            children.forEach(c -> {
                if (p.getId().equals(c.getPid())){
                    child.add(c);
                }
            });
            p.setChildren(child);
        });
    }

    @Override
    public ResponseResult addRole(Role role) throws RoleException {
        if (role.getRoleName()==null){
            throw new RoleException("传入的角色名称不能为空");
        }
        ResponseResult res=new ResponseResult();
        //处理传入的参数
        role.setRoleId(null);
        role.setPsIds(null);

        int insert = roleMapper.insert(role);
        if (insert!=0){
            res.setCreated("创建成功",role);
        }else{
            res.setError("创建失败");
        }

        return res;
    }

    @Override
    public ResponseResult selectById(Integer id) {
        ResponseResult<Role> res=new ResponseResult<>();
        Role role = roleMapper.selectById(id);
        if (role!=null){
            role.setPsIds(null);
            res.setSuccess("查询成功",role);
        }else{
            res.setNotFound("查询失败");
        }
        return res;
    }

    @Override
    public ResponseResult deleteRoleById(Integer id) {
        ResponseResult res=new ResponseResult();
        int delete = roleMapper.deleteById(id);
        if (delete!=0){
            res.setSuccess("删除成功");
            clearUserAuthorityInfoByRoleId(id);
        }else{
            res.setNotFound("删除失败,该角色不存在");
        }
        return res;
    }

    @Override
    public ResponseResult<Role> updateRole(Role role1) throws RoleException {
        if (role1.getRoleName()==null){
            throw new RoleException("修改参数传入错误");
        }
        Role role=new Role();
        role.setRoleId(role1.getRoleId());
        role.setRoleName(role1.getRoleName());
        role.setRoleDesc(role1.getRoleDesc());

        ResponseResult<Role> res=new ResponseResult<>();
        //角色名称发生改变的时候,要删除缓存中的信息(还有菜单信息,到时候补)
        int update = roleMapper.updateById(role);
        if (update!=0){
            clearUserAuthorityInfoByRoleId(role.getRoleId());
            res.setSuccess("修改成功",role);
        }else{
            res.setNotFound("角色不存在");
        }

        return res;
    }

    @Override
    public void clearUserAuthorityInfoByRoleId(Integer roleId) {
        List<Manager> managers = managerMapper.selectList(Wrappers.lambdaQuery(Manager.class).eq(Manager::getRid, roleId));
        managers.forEach(m -> {
            redisUtil.del(Const.PRE_USERNAME+m.getUsername());
        });
    }

    @Override
    public ResponseResult rightsAndRole(Role role) {
        ResponseResult res=new ResponseResult();
        int update = roleMapper.updateById(role);
        if (update!=0){
            //清除缓存信息
            clearUserAuthorityInfoByRoleId(role.getRoleId());
            res.setSuccess("更新成功");
        }else{
            res.setError("该角色不存在");
        }
        return res;
    }

    @Override
    public ResponseResult deleteRoleRights(Integer roleId, Integer rightId) throws RoleException {
        ResponseResult<List> res=new ResponseResult<>();
        Role role = roleMapper.selectById(roleId);
        if (role==null){
            throw new RoleException("该角色不存在");
        }
        String[] split = role.getPsIds().split(",");
        List<Integer> psIds = Arrays.stream(split).map(Integer::parseInt).collect(Collectors.toList());
        if (!psIds.remove(rightId)){
            throw new RoleException("该角色没有该权限");
        }
        List<Permission> permissionList = permissionMapper.selectList(Wrappers.<Permission>lambdaQuery().in(Permission::getId, psIds));
        List<PermissionApi> permissionApis=permissionApiMapper.selectList(Wrappers.<PermissionApi>lambdaQuery().in(PermissionApi::getPs_id,psIds));

        List<Permission> levelOne = mnt(permissionList, permissionApis);

        List<Permission> finalList=new ArrayList<>();
        List<Integer> finalPsIds=new ArrayList<>();

        //循环判断三级分类是否为空,为空则排除该二级分类
        //二级分类为空,为空则排除该一级分类

        //一级循环
        for (Permission permission1 : levelOne) {
            int sizeOne=0;
            if (permission1.getChildren()!=null){
                //二级循环
                List<Permission> levelTwo = permission1.getChildren();
                List<Permission> tempTwo=new ArrayList<>();
                for (Permission permission2 : levelTwo) {
                    //统计二级循环下的一级的个数
                    int sizeTwo=0;
                    if (permission2.getChildren()!=null){
                        sizeTwo=permission2.getChildren().size();
                    }
                    //一级个数为0的时候,排除该二级
                    //不为0的是添加该分类
                    if (sizeTwo!=0){
                        tempTwo.add(permission2);
                        //添加三级的id
                        for (Permission child : permission2.getChildren()) {
                            finalPsIds.add(child.getId());
                        }
                        //添加该二级的id
                        finalPsIds.add(permission2.getId());
                    }
                }
                permission1.setChildren(tempTwo);
                sizeOne=tempTwo.size();
            }

            if (sizeOne!=0){
                finalList.add(permission1);
                finalPsIds.add(permission1.getId());
            }
        }

        String psId = finalPsIds.stream().map(Object::toString).collect(Collectors.joining(","));
        role.setPsIds(psId);
        int update = roleMapper.updateById(role);
        if (update!=0){
            clearUserAuthorityInfoByRoleId(roleId);
            res.setSuccess("取消权限成功",finalList);
        }else{
            res.setError("取消权限失败");
        }
        return res;
    }

}
